home *** CD-ROM | disk | FTP | other *** search
- #include <ctype.h>
- #include <dir.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #include <io.h>
- #ifdef __GO32__
- #include <sys/farptr.h>
- #else
- #include <alloc.h>
- #endif
-
- #define extern
- #include "glob.h"
- #undef extern
- int (*__glob_sense_expand_from_proxy)(int original_expand_wildcards) = 0;
- static int expand_wildcards = 0;
-
- static void parse_chars(void *ptr, int (*func)(void *ptr));
-
- static int argv_max = 0;
-
- static int
- string_getc(void *ptr)
- {
- int c = *(*(char **)ptr)++;
- return c;
- }
-
- static int
- file_getc(void *ptr)
- {
- return fgetc((FILE *)ptr);
- }
-
- static char *
- get_proxy(int i)
- {
- int len;
- char *rv;
- int seg = __glob_proxy_vals[1];
- int ofs = __glob_proxy_vals[2];
- int c;
- #ifdef __GO32__
- _farsetsel(_go32_conventional_mem_selector());
- ofs = seg * 16 + _farnspeekw(seg*16+ofs+2*i);
- for (len=0; _farnspeekb(ofs+len); len++);
- rv = (char *)malloc(len+1);
- if (!rv)
- {
- fprintf(stderr, "Error: out of memory gathering arguments\n");
- exit(1);
- }
- for (len=0; (c = _farnspeekb(ofs+len)) != 0; len++)
- rv[len] = c;
- rv[len] = 0;
- #else
- ofs = peek(seg, ofs+2*i);
- for (len=0; peekb(seg, ofs+len); len++);
- rv = (char *)malloc(len+1);
- if (!rv)
- {
- fprintf(stderr, "Error: out of memory gathering arguments\n");
- exit(1);
- }
- for (len=0; (c = peekb(seg, ofs+len)) != 0; len++)
- rv[len] = c;
- rv[len] = 0;
- #endif
- return rv;
- }
-
- static void
- stash_arg_at(char *arg, int slot, int dup)
- {
- if (__glob_argv == 0)
- argv_max = 0;
- if (slot >= argv_max)
- {
- int newmax = (argv_max + 1)*2;
- if (__glob_argv)
- __glob_argv = (char **)realloc(__glob_argv, newmax * sizeof(char *));
- else
- {
- __glob_argv = (char **)malloc(newmax * sizeof(char *));
- __glob_argc = 0;
- argv_max = 0;
- }
- if (!__glob_argv)
- {
- fprintf(stderr, "Error: out of memory gathering arguments\n");
- exit(1);
- }
- while (argv_max < newmax)
- __glob_argv[argv_max++] = 0;
- }
- __glob_argv[slot] = arg ? (dup ? strdup(arg) : arg) : 0;
- if (arg && !__glob_argv[slot])
- {
- fprintf(stderr, "Error: out of memory gathering arguments\n");
- exit(1);
- }
- if (arg && (slot >= __glob_argc))
- __glob_argc = slot + 1;
- }
-
- static void
- stash_arg(char *arg)
- {
- stash_arg_at(arg, __glob_argc ? __glob_argc : 1, 1);
- }
-
- static void
- free_args(void)
- {
- int i;
- for (i=0; i<argv_max; i++)
- if (__glob_argv[i])
- {
- free(__glob_argv[i]);
- __glob_argv[i] = 0;
- }
- __glob_argc = 0;
- }
-
- #define SINGLE_QUOTE '\''
- #define DOUBLE_QUOTE '"'
-
- #define EOS '\0'
-
- #define isslash(c) ((c) == '\\' || (c) == '/')
-
- static char *
- rangematch(char *pattern, char test)
- {
- char c, c2;
- int negate, ok;
-
- if ((negate = (*pattern == '!')) != 0)
- ++pattern;
-
- /*
- * TO DO: quoting
- */
-
- for (ok = 0; (c = *pattern++) != ']';)
- {
- if (c == EOS)
- return(NULL); /* illegal pattern */
- if (*pattern == '-' && (c2 = pattern[1]) != EOS && c2 != ']')
- {
- if (c <= test && test <= c2)
- ok = 1;
- else if (isalpha(test) && c <= (test^0x20) && (test^0x20) <= c2)
- ok = 1;
- pattern += 2;
- }
- else if (tolower(c) == tolower(test))
- ok = 1;
- }
- return(ok == negate ? NULL : pattern);
- }
-
- static int hasdot;
-
- static int
- fnmatch(char *pattern,
- char *string)
- {
- register char c;
- char test, *rangematch();
-
- for (;;)
- switch (c = *pattern++)
- {
- case EOS:
- return(*string == EOS);
- case '?':
- if ((test = *string++) == EOS ||
- isslash(test))
- return(0);
- break;
- case '*':
- c = *pattern;
- /* collapse multiple stars */
- while (c == '*')
- c = *++pattern;
-
- /* optimize for pattern with * at end or before / */
- if (c == EOS || (c == '.' && pattern[1] == EOS && !hasdot))
- return(!strchr(string, '/'));
- else if (isslash(c))
- {
- if ((string = strpbrk(string, "/\\")) == NULL)
- return(0);
- break;
- }
-
- /* general case, use recursion */
- while ((test = *string) != EOS)
- {
- if (fnmatch(pattern, string))
- return(1);
- if (isslash(test))
- break;
- ++string;
- }
- return(0);
- case '[':
- if ((test = *string++) == EOS ||
- isslash(test))
- return(0);
- if ((pattern = rangematch(pattern, test)) == NULL)
- return(0);
- break;
- default:
- string++;
- if (tolower(c) != tolower(string[-1]))
- return(0);
- break;
- }
- }
-
-
-
- #define PATH_MAX 140
-
- static int lowcase = 0;
- static int mustexist = 0;
-
- static void
- wildcard1(char *buf, char *bp, char *fp)
- {
- char *slpos = strpbrk(fp, "/\\"), slsave='-';
- int done, i;
- struct ffblk ff;
- char *wildchars;
- if (slpos)
- {
- slsave = *slpos;
- *slpos = 0;
- }
- for (i=0; fp[i]; i++)
- {
- if (islower(fp[i]))
- lowcase = 1;
- if (isupper(fp[i]))
- lowcase = 0;
- }
- wildchars = strpbrk(fp, "*?[]");
- if (!expand_wildcards || wildchars==0)
- {
- strcpy(bp, fp);
- if (slpos)
- {
- int bpl = strlen(bp);
- bp[bpl++] = slsave;
- bp[bpl] = 0;
- wildcard1(buf, bp+bpl, slpos+1);
- }
- else
- {
- if (wildchars == 0 && mustexist)
- {
- if (access(buf, 0) == 0)
- stash_arg(buf);
- }
- else
- stash_arg(buf);
- }
- }
- else
- {
- strcpy(bp, "*.*");
- done = findfirst(buf, &ff, FA_RDONLY|FA_DIREC|FA_ARCH);
- while (!done)
- {
- if (ff.ff_name[0] != '.' || fp[0] == '.')
- {
- if (lowcase)
- strlwr(ff.ff_name);
- hasdot = strchr(ff.ff_name, '.')!=0;
- if (fnmatch(fp, ff.ff_name))
- {
- strcpy(bp, ff.ff_name);
- if (slpos)
- {
- int bpl = strlen(bp);
- bp[bpl++] = slsave;
- bp[bpl] = 0;
- mustexist++;
- wildcard1(buf, bp+bpl, slpos+1);
- mustexist--;
- }
- else
- stash_arg(buf);
- }
- }
- done = findnext(&ff);
- }
- }
- if (slpos)
- *slpos = slsave;
- }
-
- static int
- argv_cmp(void *av, void *bv)
- {
- register char *a = *(char **)av;
- register char *b = *(char **)bv;
- return strcmp(a, b);
- }
-
- static void
- wildcard(char *arg)
- {
- char buf[140];
- char *bp, *fp;
- int oarg;
-
- lowcase = 1;
- bp=buf;
- fp=arg;
- if (fp[1] == ':')
- {
- *bp++ = *fp++;
- *bp++ = *fp++;
- }
- if (*fp == '/' || *fp == '\\')
- *bp++ = *fp++;
- oarg = __glob_argc;
- if (oarg < 1) oarg = 1;
- wildcard1(buf, bp, fp);
- if (oarg >= __glob_argc)
- stash_arg(arg);
- else
- qsort(__glob_argv+oarg, __glob_argc - oarg,
- sizeof(char *), argv_cmp);
- }
-
- static void
- expand_arg(char *arg)
- {
- if (arg[0] == '@')
- {
- FILE *f = fopen(arg+1, "r");
- if (f)
- {
- parse_chars(f, file_getc);
- fclose(f);
- return;
- }
- }
- else if (expand_wildcards && strspn("*?[]", arg))
- wildcard(arg);
- else
- stash_arg(arg);
- }
-
- static void
- parse_chars(void *ptr, int (*func)(void *ptr))
- {
- int quote = 0;
- int needs_expansion = 0;
- char argbuf[1000];
- char *start = argbuf;
- int pending_arg = 0;
- int done = 0;
- int unc = -2;
-
- while (!done)
- {
- int c = (unc==-2) ? func(ptr) : unc;
- unc = -2;
- if (c <= 0)
- {
- if (pending_arg)
- {
- *start = 0;
- if (needs_expansion)
- expand_arg(argbuf);
- else
- stash_arg(argbuf);
- pending_arg = 0;
- start = argbuf;
- }
- done = 1;
- }
- else if (quote == SINGLE_QUOTE)
- {
- if (c == SINGLE_QUOTE)
- quote = 0;
- else
- *start++ = c;
- }
- else if (quote == DOUBLE_QUOTE)
- {
- if (c == DOUBLE_QUOTE)
- quote = 0;
- else if (c == '\\')
- {
- unc = func(ptr);
- if (strchr("\\'\"", unc))
- {
- *start++ = unc;
- unc = -2;
- }
- else if (unc != '\n')
- {
- *start++ = c;
- }
- }
- else
- *start++ = c;
- }
- else if (isspace(c))
- {
- if (pending_arg)
- {
- *start = 0;
- if (needs_expansion)
- expand_arg(argbuf);
- else
- stash_arg(argbuf);
- pending_arg = 0;
- start = argbuf;
- }
- }
- else
- {
- if (c == SINGLE_QUOTE || c == DOUBLE_QUOTE)
- quote = c;
- else if (c == '\\')
- {
- unc = func(ptr);
- if (unc == '\n')
- unc = -2;
- else if (strchr("\\'\"", unc) || isspace(unc))
- {
- *start++ = unc;
- unc = -2;
- }
- else
- *start++ = '\\';
- }
- else
- {
- if (strchr("*?[]", c) || (c == '@' && start == argbuf))
- needs_expansion = 1;
- *start++ = c;
- }
- pending_arg = 1;
- }
- }
- }
-
- static int
- getenvargs(void)
- {
- int i, ac;
- char aname[10];
- char *a0 = getenv("_argc");
- if (!a0)
- return 1;
- ac = atoi(a0);
- for (i=0; i<ac; i++)
- {
- sprintf(aname, "_argv%d", i);
- if (i == 0)
- stash_arg_at(getenv(aname), 0, 1);
- else
- expand_arg(getenv(aname));
- }
- return 0;
- }
-
- void
- __glob_args(char *cmdline, char *dos_argv0, int _expand_wildcards)
- {
- expand_wildcards = _expand_wildcards;
- free_args();
- __glob_argc = 0;
- __glob_proxy_count = 0;
-
- if (getenvargs())
- {
- parse_chars(&cmdline, string_getc);
-
- if (__glob_argc > 4 && strcmp(__glob_argv[1], "!proxy") == 0)
- {
- int i;
- for (i=0; i+2 < __glob_argc; i++)
- {
- unsigned long pval = strtoul(__glob_argv[i+2], 0, 16);
- __glob_proxy_vals[i] = (unsigned) pval;
- }
- free_args();
- __glob_proxy_count = i;
- if (__glob_sense_expand_from_proxy)
- expand_wildcards = __glob_sense_expand_from_proxy(expand_wildcards);
- stash_arg_at(get_proxy(0), 0, 1);
- for (i=1; i<__glob_proxy_vals[0]; i++)
- expand_arg(get_proxy(i));
- }
- else
- stash_arg_at(dos_argv0, 0, 1);
- }
-
- stash_arg_at(0, __glob_argc, 0);
- }
-
- void
- __glob_env(char *app_name)
- {
- FILE *djgpp_env;
- char *djgpp_var = getenv("DJGPP");
- char *copy;
-
- if (djgpp_var)
- {
- djgpp_env = fopen(djgpp_var, "rt");
- if (djgpp_env)
- {
- char line[2000];
- char base[12], *bp, *a0p, *tb = (char *)line;
- int this_prog = 1;
- base[0] = '[';
- bp = app_name;
- for (a0p = bp; *a0p; a0p++)
- if (strchr("\\/:", *a0p))
- bp = a0p+1;
- for (a0p=base+1; *bp && *bp != '.';)
- *a0p++ = tolower(*bp++);
- *a0p++ = ']';
- *a0p++ = 0;
- while (fgets(tb, 2000, djgpp_env))
- {
- tb[strlen(tb)-1] = 0;
- if (tb[0] == 0)
- continue;
- if (tb[0] == '[')
- {
- if (strcmp(tb, base) == 0)
- this_prog = 1;
- else
- this_prog = 0;
- }
- else
- {
- if (this_prog)
- {
- char *tb2 = tb+strlen(tb)+1;
- char *sp=tb, *dp=tb2;
- while (*sp != '=')
- *dp++ = *sp++;
- if (*tb2 == '+') /* non-overriding */
- {
- *dp = 0;
- tb2++;
- if (getenv(tb2))
- continue; /* while fread */
- }
- *dp++ = *sp++; /* copy the '=' */
- while (*sp)
- {
- if (*sp == '%')
- {
- char *pp;
- if (sp[1] == '%')
- {
- *dp++ = '%';
- sp += 2;
- }
- else
- {
- char ps, *e, *dirend;
- int dirpart=0, apsemi=0;
- int mapup=0, maplow=0, mapfs=0, mapbs=0;
- while (strchr(":;/\\<>", sp[1]))
- {
- switch (sp[1])
- {
- case ':': dirpart=1; break;
- case ';': apsemi=1; break;
- case '/': mapfs=1; break;
- case '\\': mapbs=1; break;
- case '<': mapup=1; break;
- case '>': maplow=1; break;
- }
- sp++;
- }
- for (pp=sp+1; *pp && *pp != '%'; pp++);
- ps = *pp;
- *pp = 0;
- e = getenv(sp+1);
- dirend = dp;
- if (e)
- {
- while (*e)
- {
- char ec = *e++;
- if (strchr("\\/:", ec))
- dirend=dp;
- if (mapup) ec = toupper(ec);
- if (maplow) ec = tolower(ec);
- if (mapfs && ec == '\\') ec = '/';
- if (mapbs && ec == '/') ec = '\\';
- *dp++ = ec;
- }
- }
- if (dirpart)
- dp = dirend;
- if (apsemi && e)
- *dp++ = ';';
- if (ps == 0)
- break;
- sp = pp+1;
- }
- }
- else
- *dp++ = *sp++;
- }
- *dp++ = 0;
- copy = strdup(tb2);
- if (!copy)
- {
- fprintf(stderr, "Error: out of memory gathering environment\n");
- exit(1);
- }
- putenv(copy);
- }
- }
- }
- fclose(djgpp_env);
- }
- }
- }
-